package com.ls.component.security.intercetor;


import com.alibaba.fastjson.JSONObject;
import com.central.common.constant.ExtendConstant;
import com.central.common.model.Result;
import com.ls.component.security.properties.CloudSecurityProperties;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Base64Utils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @program: central-platform
 * @author: lishuai
 * @create: 2022-02-08 18:22
 * 用于校验请求是否经过网关
 */
@Slf4j
public class ServerProtectInterceptor implements HandlerInterceptor {
    //在请求经过网关时添加额外的Header，为了方便这里直接设置成固定值
    //private final static String backend_access_token = "backend_access_token";

    private CloudSecurityProperties properties;

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler){

        if (!properties.getOnlyFetchByGateway()) {
            return true;
        }

        String token = request.getHeader(ExtendConstant.backend_access_token);

        String requestURI = request.getRequestURI().trim();
        log.info("请求的URI：{},token:{}",requestURI,token);
        //针对@LoginUser注解，在解析参数的时候会再次调用user服务的http接口，这里因此需要做个处理@GetMapping(value = "/users/name/{username}")
        if (requestURI.startsWith("/users/name/")) {
            log.info("获取当前登录用户信息接口不进行拦截放行");
            return true;
        }

        String gatewayToken = new String(Base64Utils.encode(ExtendConstant.backend_access_token.getBytes()));

        if (StringUtils.equals(gatewayToken, token)) {
            return true;
        } else {
            log.error("非法请求，请通过网关访问资源");
            Result<String> resultData = new Result<>();
            resultData.setResp_code(HttpServletResponse.SC_FORBIDDEN);
            resultData.setResp_msg("请通过网关访问资源");
            ajaxErrorResponse(response,resultData);

            return false;
        }
    }

    public void setProperties(CloudSecurityProperties properties) {
        this.properties = properties;
    }
    private void ajaxErrorResponse(HttpServletResponse response, Object object) {
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write(JSONObject.toJSONString(object));
            writer.flush();
        } catch (IOException e) {
            log.error("ajaxErrorResponse error", e);
        } finally {
            IOUtils.closeQuietly(writer);
        }
    }
}
